  ---@diagnostic disable: undefined-field, param-type-mismatch
local extension=Package("xiaobai-twelve")
extension.extensionName="xiaobai"

Fk:loadTranslationTable{
  ["xiaobai-twelve"]="十二届小白杯",
}
local U = require "packages/utility/utility"
local DIY = require "packages/diy_utility/diy_utility"

local function AddWinAudio(general)
  local Win = fk.CreateActiveSkill{ name = general.name.."_win_audio" }
  Win.package = extension
  Fk:addSkill(Win)
end

local maohuanghou = General(extension,"xiaobai-twelve__maohuanghou", "wei",3,3,General.Female)

local nianxing_choose = fk.CreateActiveSkill{
  name = "#nianxing_choose",
  interaction = function ()
    local all_choices = {"nianxing_usecard","nianxing_discard"}
    if Self:getMark("nianxing_discard") == 0 then
      return UI.ComboBox{
        choices = all_choices,
        all_choices = all_choices,
      }
    else
      return UI.ComboBox{
        choices = {all_choices[2]},
        all_choices = {all_choices[2]},
      }
    end
  end,
  card_num = 1,
  card_filter = function (self, to_select, selected, player)
    if not self.interaction.data or (selected and #selected>0)  then return end
    if self.interaction.data == "nianxing_usecard" then
      return table.contains(player.player_cards[Player.Hand], to_select) and Fk:getCardById(to_select).type == Card.TypeEquip
    else
      return Fk:getCardById(to_select).type == Card.TypeEquip
    end
  end
}
Fk:addSkill(nianxing_choose)

local nianxing = fk.CreateViewAsSkill{
  name = "xiaobai__nianxing",
  dynamic_desc = function (self, player, lang)
    local text = "xiaobai__nianxing_prompt1:"
    if player:getMark("nianxing_discard")==0 then
        text = text.."xiaobai__nianxing_prompt2:"
    else
      text = text .. ":"
    end
    if player:getMark("nianxing_jink")==0 then
      text = text.."xiaobai__nianxing_prompt3"
    else
    text = text .. ""
  end
    return text
  end,
  pattern = "jink,nullification",
  anim_type = "defensive",
  interaction = function()
    local all_names = {
      "jink","nullification"
    }
    if Self:getMark("nianxing_jink")>0 then
      all_names = {
        "jink"
      }
    end
    local names = {}
    for _, name in ipairs(all_names) do
      local card = Fk:cloneCard(name)
      if (Fk.currentResponsePattern == nil and Self:canUse(card)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
        table.insertIfNeed(names, card.name)
      end
    end
    if #names == 0 then return end
    return UI.CardNameBox {choices = names}
  end,
  card_filter = Util.FalseFunc,
  before_use = function (self, player, use)
    local room = player.room
    local done,use = room:askForUseActiveSkill(player,"#nianxing_choose","#nianxiang_choose_cost")
    if not done then return self.name end
    if use.interaction == "nianxing_discard" then
      room:addPlayerMark(player,"nianxing_discard")
      room:throwCard(use.cards,self.name,player,player)
      if not player.dead then return end
    else
      room:useCard{
        card = Fk:getCardById(use.cards[1]),
        from = player.id,
        tos = {{player.id}},
      } 
      if not player.dead then return end
    end
    return self.name
  end,
  view_as = function (self,cards)
    if #cards ~= 0 or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  after_use = function (self, player, use)
    if use.card.trueName == "jink" then
      player.room:addPlayerMark(player,"nianxing_jink")
    end
  end,
  enabled_at_response = function (self, player, response)
    return not response and Exppattern:Parse(Fk.currentResponsePattern):match(Fk:cloneCard("jink")) or (player:getMark("nianxing_jink") == 0) and 
      table.find(player:getCardIds("he"),function (element, index, array)
        return Fk:getCardById(element).type == Card.TypeEquip
      end)
  end
}

local rongai = fk.CreateTriggerSkill{
  name = "xiaobai__rongai",
  events = {fk.TurnStart,fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    if event == fk.TurnStart then
      return player:hasSkill(self) and target ~= player and ((player:getMark("xiaobai__rongai1-round") == 0 and player:getHandcardNum()~=1) or 
        player:getMark("xiaobai__rongai4-round") == 0 and player:getHandcardNum()~=4)
    else
      return player:hasSkill(self) and target ~= player and (player:getMark("xiaobai__rongaic1-turn") == 0 or player:getMark("xiaobai__rongaic4-turn"))
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TurnStart then
      if player.room:askForSkillInvoke(player,self.name) then
        local all_choices = {"xiaobai__rongai_change1","xiaobai__rongai_change4"}
        local choices = {}
        if player:getMark("xiaobai__rongai1-round") == 0 and player:getHandcardNum()~=1 then
          table.insert(choices,all_choices[1])
        end
        if player:getMark("xiaobai__rongai4-round") == 0  and player:getHandcardNum()~=4 then
          table.insert(choices,all_choices[2])
        end
        local r = player.room:askForChoice(player,choices,self.name,"",false,all_choices)
        if not r then return end
        self.cost_data = {response = r}
        return true
      end
    else
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    if event == fk.TurnStart then
      if self.cost_data.response == "xiaobai__rongai_change1" then
        player.room:setPlayerMark(player,"xiaobai__rongai1-round",1)
        player.room:setPlayerMark(player,"xiaobai__rongaic4-turn",1)
        local num = player:getHandcardNum() - 1
        if num < 0 then
          player:drawCards(-num,self.name)
        elseif num> 0 then
          player.room:askForDiscard(player,num,num,false,self.name,false,".")
        end
      else
        player.room:setPlayerMark(player,"xiaobai__rongai4-round",1)
        player.room:setPlayerMark(player,"xiaobai__rongaic1-turn",1)
        local num = player:getHandcardNum() - 4
        if num < 0 then
          player:drawCards(-num,self.name)
        elseif num> 0 then
          player.room:askForDiscard(player,num,num,false,self.name,false,".")
        end
      end
    else
      if player:getMark("xiaobai__rongaic4-turn") then
        if #player.room.logic:getActualDamageEvents(1,function (e)
          return e.data[1].to == player
        end,Player.HistoryTurn) >0 then
          local num = player:getHandcardNum() - 4
          if num < 0 then
            player:drawCards(-num,self.name)
          elseif num> 0 then
            player.room:askForDiscard(player,num,num,false,self.name,false,".")
          end
        end
      else
        if #player.room.logic:getActualDamageEvents(1,function (e)
          return e.data[1].to == player
        end,Player.HistoryTurn) >0 then
          local num = player:getHandcardNum() - 1
          if num < 0 then
            player:drawCards(-num,self.name)
          elseif num> 0 then
            player.room:askForDiscard(player,num,num,false,self.name,false,".")
          end
        end
      end
    end
  end
}

maohuanghou:addSkill(nianxing)
maohuanghou:addSkill(rongai)

Fk:loadTranslationTable{
  ["xiaobai-twelve__maohuanghou"] = "毛皇后",
  ["#xiaobai-twelve__maohuanghou"] = "华落沉渊",
  ["illustrator:xiaobai-twelve__maohuanghou"] = "匠人绘",
  ["designer:xiaobai-twelve__maohuanghou"] = "末页",
  ["cv:xiaobai-twelve__maohuanghou"] = "桃妮儿",

  ["xiaobai__nianxing"] = "辇幸",
  [":xiaobai__nianxing"] = "每回合限一次，你可以使用或弃置一张装备牌，"..
    "视为使用一张【无懈可击】或【闪】，当你选择了“弃置”或“使用【闪】”后，删去对应的另一选项。",
  [":xiaobai__nianxing_prompt1"] = "每回合限一次，你可以{1}弃置一张装备牌，视为使用一张{2}【闪】，当你选择了“弃置”或“使用【闪】”后，删去对应的另一选项。",
  ["xiaobai__nianxing_prompt2"] = "使用或",
  ["xiaobai__nianxing_prompt3"] = "【无懈可击】或",
  ["#nianxiang_choose_cost"] = "辇幸：请选择使用或弃置一张装备牌",
  ["#nianxing_choose"] = "辇幸",
  ["nianxing_usecard"] = "使用一张装备牌",
  ["nianxing_discard"] = "弃置一张装备牌",

  ["xiaobai__rongai"] = "荣哀",
  [":xiaobai__rongai"] = "每轮各限一次，其他角色的回合开始时，你可以将手牌数调整为1或4，回合结束时，若你本回合受到过伤害，你将手牌数调整为另一值。",
  ["xiaobai__rongai_change1"] = "调整至1张",
  ["xiaobai__rongai_change4"] = "调整至4张",


  ["$xiaobai__nianxing1"] = "一簇相倾，百丛相妒，芳心何怕东君误。",
  ["$xiaobai__nianxing2"] = "桃李争春，我随孟夏长停步。",
  ["$xiaobai__rongai1"] = "似雨知心，如风识路，何须世上虚名度？",
  ["$xiaobai__rongai2"] = "相逢佳时，此番约定同君住。",
  ["~xiaobai-twelve__maohuanghou"] = "芳菲住、来年付，花可有归处？"
}

local malun = General(extension,"xiaobai-twelve__malun", "qun",3,3,General.Female)

local bianmei = fk.CreateActiveSkill{
  name = "xiaobai__bianmei",
  anim_type = "control",
  prompt = "#xiaobai__bianmei_prompt",
  can_use = function (self, player, card, extra_data)
    return player:usedSkillTimes(self.name) < 1 and player:getHandcardNum() > 0 and
      table.find(Fk:currentRoom().alive_players, function (p)
        return p:getHandcardNum() - player:getHandcardNum() == 1
      end)
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0  and Fk:currentRoom():getPlayerById(to_select):getHandcardNum() - player:getHandcardNum() == 1
  end,
  feasible = function (self, selected, selected_cards, player)
    return #selected == 1
  end,
  on_use = function (self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local pindian = player:pindian({target}, self.name)
    room:pindian(pindian)
    local winner = pindian.results[target.id].winner
    local loser = winner == player and target or player
    if winner then
      if winner.dead then return end
      if room:askForSkillInvoke(winner, self.name, nil, "xiaobai__bianmei_askForDraw2::"..loser.id) then
        winner:drawCards(2, self.name)
        if loser.dead then return end
        if winner == player then
          room:obtainCard(target, pindian.results[target.id].toCard, true, fk.ReasonPrey, player.id, self.name)
        else
          room:obtainCard(player, pindian.fromCard, true, fk.ReasonPrey, player.id, self.name)
        end
      else
        winner:drawCards(1 ,self.name)
      end
      if player.dead then return end
      while player == winner do
        local done,data = room:askForUseActiveSkill(player, self.name)
        if done and data then
          target = room:getPlayerById(data.targets[1])
          pindian = player:pindian({target}, self.name)
          winner = pindian.results[target.id].winner
          loser = (winner == player and target or player)
          if winner then
            if winner.dead then return end
            if room:askForSkillInvoke(winner, self.name, nil, "xiaobai__bianmei_askForDraw2::"..loser.id) then
              winner:drawCards(2, self.name)
              if loser.dead then return end
              if winner == player then
                room:obtainCard(target, pindian.results[target.id].toCard, true, fk.ReasonPrey, player.id, self.name)
              else
                room:obtainCard(player, pindian.fromCard, true, fk.ReasonPrey, player.id, self.name)
              end
            else
              winner:drawCards(1 ,self.name)
            end
            if player.dead then return end
          end
        else
          break
        end
      end
    end
  end
}

local yingying = fk.CreateViewAsSkill{
  name = "xiaobai__yingying",
  pattern = "slash,jink",
  card_filter = function (self, to_select, selected, player)
    local handCardNum = player:getHandcardNum()
    local maxCardNum = player:getMaxCards()
    if handCardNum > maxCardNum then return table.contains(player:getCardIds("h"), to_select) and #selected < (handCardNum - maxCardNum)
    else return false end
  end,
  interaction = function()
    local names = {}
    for _, name in ipairs({"slash","jink"}) do
      local card = Fk:cloneCard(name)
      if (Fk.currentResponsePattern == nil and Self:canUse(card)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
        table.insertIfNeed(names, card.name)
      end
    end
    if #names == 0 then return end
    return UI.CardNameBox {choices = names}
  end,
  view_as = function (self, cards, player)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    local handCardNum = player:getHandcardNum()
    local maxCardNum = player:getMaxCards()
    if #cards == handCardNum - maxCardNum then
      self.cost_data = cards
    elseif handCardNum - maxCardNum > 0 then
      return nil
    end
    return card
  end,
  before_use = function (self, player, use)
    local room = player.room
    local difference = player:getHandcardNum() - player:getMaxCards()
    if difference > 0 then
      room:throwCard(self.cost_data, self.name, player)
      room:addPlayerMark(player, "xiaobai__yingying_discard", #self.cost_data)
      if player:getMark("xiaobai__yingying_discard") >= player:getMark("xiaobai__yingying_draw") then
        room:removePlayerMark(player, "@@xiaobai__yingying_cantDraw")
      end
    else
      player:drawCards(-difference, self.name)
      room:addPlayerMark(player, "xiaobai__yingying_draw", -difference)
      if player:getMark("xiaobai__yingying_discard") < player:getMark("xiaobai__yingying_draw") then
        room:addPlayerMark(player, "@@xiaobai__yingying_cantDraw")
      end
    end
  end,
  enabled_at_play = function (self, player)
    if player:getHandcardNum() < player:getMaxCards() then
      return player:getMark("@@xiaobai__yingying_cantDraw") == 0
    else
      return player:getHandcardNum() > player:getMaxCards()
    end
  end,
  enabled_at_response = function (self, player, response)
    if player:getHandcardNum() < player:getMaxCards() then
      return player:getMark("@@xiaobai__yingying_cantDraw") == 0
    else
      return player:getHandcardNum() > player:getMaxCards()
    end
  end
}

malun:addSkill(bianmei)
malun:addSkill(yingying)

Fk:loadTranslationTable{
  ["xiaobai-twelve__malun"] = "马伦",
  ["#xiaobai-twelve__malun"] = "慧臻端节",
  ["illustrator:xiaobai-twelve__malun"] = "椰蓉白大福", 
  ["designer:xiaobai-twelve__malun"] = "易大剧",

  ["xiaobai__bianmei"] = "辩眉",
  [":xiaobai__bianmei"] = "出牌阶段限一次，你可以与一名手牌比你多一张的角色拼点，赢者可以摸一张牌，或摸两张牌并令对方获得其拼点牌，若你赢，你可以再发动一次“辩眉”。",
  ["#xiaobai__bianmei_prompt"] = "辩眉：你可以与一名手牌比你多一张的角色拼点，赢者可以摸一张牌，或摸两张牌并令对方获得其拼点牌，若你赢，你可以再发动一次“辩眉”",

  ["xiaobai__bianmei_askForDraw2"] = "你可以点击“确定”摸两张牌并令 %dest 获得其拼点牌，或点击“取消”摸一张牌",

  ["xiaobai__yingying"] = "营盈",
  [":xiaobai__yingying"] = "你可以将手牌数调整为手牌上限，视为使用或打出【杀】或【闪】。若你因“营盈”累计的摸牌数大于弃牌数，则你只能通过弃牌发动“营盈”。",
  ["@@xiaobai__yingying_cantDraw"] = "营盈 仅弃牌"
}


local liuhong = General:new (extension, "xiaobai-twelve__liuhong", "qun", 3)

AddWinAudio(liuhong)

Fk:loadTranslationTable{
  ["xiaobai-twelve__liuhong"] = "刘洪",
  ["#xiaobai-twelve__liuhong"] = "算圣",
  ["designer:xiaobai-twelve__liuhong"] = "小叶子",
  ["illustrator:xiaobai-twelve__liuhong"] = "查无",
  ["cv:xiaobai-twelve__liuhong"] = "文小鸢",

  ["~xiaobai-twelve__liuhong"] = "推之历法、验之日食，恐天下将乱…",
  ["$xiaobai-twelve__liuhong_win_audio"] = "日月五星、列居错峙，以为定纪，以备天官。"
}



local qianxiang = fk.CreateTriggerSkill{
  name = "xiaobai__qianxiang",
  anim_type = "control",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    return player:getMark("@qianxiang_qian") >0 and player:getMark("@qianxiang_kun") >0 and 
      player:hasSkill(self)
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local difference = player:getMark("@qianxiang_qian") - player:getMark("@qianxiang_kun")
    if difference == 0 then 
      if player.room:askForSkillInvoke(player,self.name,nil,"#do_change:::"..0) then 
        player.room:throwCard(player:getCardIds(Player.Hand), self.name, player, player) 
      end 
      return 
    end
    if difference < 0 then
      difference = -difference
    end
    if difference >5 then difference = 5 end
    local cards = player.room:getNCards(difference,"top")
    local use = U.askForUseRealCard(player.room,player,cards,".",self.name,"#qianxiang_ask:::"..difference..":::"..difference,
      {bypass_time = true,extraUse = true,expand_pile = cards})
    if not use and player.room:askForSkillInvoke(player,self.name,nil,"#do_change:::"..difference)then
      local num = difference - player:getHandcardNum()
      if num > 0 then
        player:drawCards(num, self.name)
      elseif num < 0 then
        player.room:askForDiscard(player, -num, -num, false, self.name, false)
      end
    end
  end,
  refresh_events = {fk.AfterCardsMove,fk.EventAcquireSkill,fk.EventLoseSkill,fk.AfterTurnEnd},
  can_refresh = function (self, event, target, player, data)
    return (player:hasSkill(self,true) or event == fk.EventLoseSkill) and 
      (event ~= fk.EventLoseSkill or (target == player and data == self)) and 
      (event ~= fk.EventAcquireSkill or (target == player and data == self)) 
  end,
  on_refresh = function (self, event, target, player, data)
    if event == fk.AfterCardsMove then
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerEquip or info.fromArea == Card.PlayerHand then
              player.room:addPlayerMark(player,"@qianxiang_qian")
            end
          end
        end
        if move.to == player.id and (move.toArea == Card.PlayerHand or move.toArea == Card.PlayerEquip)then
          for _, info in ipairs(move.moveInfo) do
            player.room:addPlayerMark(player,"@qianxiang_kun")
          end
        end
      end
    elseif event == fk.EventAcquireSkill then
      player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.from == player.id then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerEquip or info.fromArea == Card.PlayerHand then
                player.room:addPlayerMark(player,"@qianxiang_qian")
              end
            end
          end
          if move.to == player.id and (move.toArea == Card.PlayerHand or move.toArea == Card.PlayerEquip) then
            for _, info in ipairs(move.moveInfo) do
              player.room:addPlayerMark(player,"@qianxiang_kun")
            end
          end
        end
      end, Player.HistoryTurn)
    else
      player.room:setPlayerMark(player,"@qianxiang_qian",0)
      player.room:setPlayerMark(player,"@qianxiang_kun",0)
    end
  end,

}



liuhong:addSkill(touzhu)
liuhong:addSkill(qianxiang)

local sunshao  = General(extension,"xiaobai-twelve__sunshao", "wu", 4)

Fk:loadTranslationTable{
  ["xiaobai-twelve__sunshao"] = "孙韶",
  ["#xiaobai-twelve__sunshao"] = "革营益进",
  ["illustrator:xiaobai-twelve__sunshao"] = "NOVART",
  ["designer:xiaobai-twelve__sunshao"] = "柠檬"
}

local leicheng = fk.CreateTriggerSkill{
  name = "xiaobai__leicheng",
  events = {fk.CardUsing},
  anim_type = "drawcard",
  priority = 2,
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and data.card.type == Card.TypeEquip and player==target
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = nil
    local all_choices = {
      "#use_card_as_await_exhausted_empty",
      "#draw2four",
      "Cancel"
    }
    local choices = {all_choices[2],"Cancel"}
    room.logic:getEventsByRule(GameEvent.UseCard, 1, function (e)
      if e.id ~= room.logic:getCurrentEvent().id then
        local use = e.data[1]
        if use.card.type == Card.TypeEquip then
          to = room:getPlayerById(use.from)
          return true
        end
      end
    end, 1)
    
    self.cost_data = {}
    if to~= nil and not to:isNude() then
      all_choices[1] = "#use_card_as_await_exhausted::"..to.id
      table.insert(choices,1,all_choices[1])
      self.cost_data.to = to
    end
    local choice = room:askForChoice(player,choices,self.name,"xiaobai__leicheng",false,all_choices)
    if choice~= "Cancel" then
      self.cost_data.choice = choice
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if self.cost_data.choice:startsWith("#use_card_as_await_exhausted") then
      local to = self.cost_data.to
      local card = room:askForCardChosen(player,to,"he",self.name,"#leicheng_chooseCard::"..to.id)
      room:useVirtualCard("await_exhausted",{card},player,player,self.name)
    else
      if player:getHandcardNum() < 4 then
        local draw_num = 4-player:getHandcardNum()
        room:drawCards(player,draw_num,self.name)
      end
      room:setPlayerMark(player,"leicheng_next-trigger",1)
    end
  end
}

local leicheng_delay = fk.CreateTriggerSkill{
  name = "#leicheng_delay",
  events = {fk.CardUsing},
  mute = true,
  priority = 1,
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self,true) and ((player:getMark("@@leicheng_next") > 0 and data.card.type == Card.TypeEquip and player:getHandcardNum() > 0) or player:getMark("leicheng_next-trigger") > 0)
  end,
  frequency = Skill.Compulsory,
  on_use = function (self, event, target, player, data)
    if player:getMark("@@leicheng_next") > 0 then
      if not player:isNude() then
        local card  = player.room:askForCardChosen(target,player,"h","xiaobai__leicheng","#leicheng_choose2discard::"..player.id)
        player.room:throwCard({card},"xiaobai__leicheng",player,target)
      end
      if player.dead then return end
      player.room:setPlayerMark(player,"@@leicheng_next",0)
    end
    if player:getMark("leicheng_next-trigger") > 0 then
      player.room:setPlayerMark(player,"leicheng_next-trigger",0)
      player.room:setPlayerMark(player,"@@leicheng_next",1)
    end
  end,
}

leicheng:addRelatedSkill(leicheng_delay)

Fk:loadTranslationTable{
  ["xiaobai__leicheng"] = "垒城",
  [":xiaobai__leicheng"] = "当你使用装备牌时，可以选择一项：1.将上一名使用装备牌的角色的一张牌当【以逸待劳】对你使用。2.摸至四张牌，然后有角色下次使用装备时，其弃置你一张手牌。",
  ["#use_card_as_await_exhausted"] = "将 %dest 的一张牌当【以逸待劳】对你使用",
  ["#use_card_as_await_exhausted_empty"] = "将上一名角色的一张牌当【以逸待劳】对你使用",
  ["#draw2four"] = "摸至四张牌，然后有角色下次使用装备时，其弃置你一张手牌",
  ["@@leicheng_next"] = "垒城",
  ["#leicheng_choose2discard"] = "垒城：弃置 %dest 的一张手牌",
  ["#leicheng_chooseCard"] = "垒城：请选择 %dest 的一张手牌"
}

local liehe = fk.CreateTriggerSkill{
  name = "xiaobai__liehe",
  events = {fk.TurnEnd},
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    local evt = player.room.logic:getEventsOfScope(
      GameEvent.MoveCards,1,function (e)
        for _, move in ipairs(e.data) do
          if move.from == player.id then
            return true
          end
        end
      end,Player.HistoryTurn
    )
    return evt and #evt>0
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to  = room.current
    local difference = #player:getCardIds("e") - #to:getCardIds("e")
    local types = {"weapon","armor","defensive_ride","offensive_ride","treasure"}
    self.cost_data = {}
    local moveTargets = table.filter(room:getOtherPlayers(player),function (element, index, array)
      return element ~= to and player:canMoveCardsInBoardTo(element,"e")
    end)
    if difference == 1 then
      local all_choices = {"liehe_use::"..to.id,"liehe_get::"..player.id,"liehe_move_other::"..player.id,"Cancel"}
      local can_choose = {true,#player:getCardIds("e")>0,#moveTargets>0,true}
      local choices = table.filter(all_choices,function (element, index, array)
        return can_choose[index]
      end)
      local choice = room:askForChoice(player,choices,self.name,"#liehe_use",false,all_choices)
      if choice == "Cancel" then
        return false
      elseif choice:startsWith("liehe_use") then
        local type = table.concat(table.map(
          table.filter({Card.SubtypeWeapon, Card.SubtypeArmor, Card.SubtypeDefensiveRide,Card.SubtypeOffensiveRide, Card.SubtypeTreasure}, 
            function (type_name) return not player:getEquipment(type_name) end),
          function (element, index, array)return types[index]end),',')
        local card = U.askForUseRealCard(room,to,to:getHandlyIds(true),".|.|.|.|.|"..type,self.name,"#liehe_askUse",nil,true)
        if card then
          self.cost_data.card = card
          self.cost_data.operation = 1
          return true
        end
      elseif choice:startsWith("liehe_get") then
        local card = room:askForCard(player,1,1,true,self.name,false,".|.|.|.|.|equip","#liehe_getEquip")
        if card then
          self.cost_data.card = card
          self.cost_data.executor = player
          self.cost_data.operation = 2
          return true
        end
      else
        local moveTo = room:askForChoosePlayers(player,table.map(moveTargets,Util.IdMapper),1,1,"liehe_choose2Move",self.name,false)
        if moveTo and #moveTo>0 then
          self.cost_data.target = moveTo[1]
          self.cost_data.executor = player
          self.cost_data.operation = 3
          return true
        end
      end
      return true
    elseif difference == -1 then
      local moveTargets = table.filter(room:getOtherPlayers(to),function (element, index, array)
        return element ~= player and to:canMoveCardsInBoardTo(element,"e")
      end)
      local all_choices = {"liehe_use::"..player.id,"liehe_get_or_move_other::"..to.id,"Cancel"}
      local can_choose = {true,#to:getCardIds("e")>0 or #moveTargets>0,true}
      local choices = table.filter(all_choices,function (element, index, array)
        return can_choose[index]
      end)
      local choice = room:askForChoice(player,choices,self.name,"#liehe_use",false,all_choices)
      if choice == "Cancel" then
        return false
      elseif choice:startsWith("liehe_use") then
        local type = table.concat(table.map(
          table.filter({Card.SubtypeWeapon, Card.SubtypeArmor, Card.SubtypeDefensiveRide,Card.SubtypeOffensiveRide, Card.SubtypeTreasure}, 
            function (type_name) return not to:getEquipment(type_name) end),
          function (element, index, array)return types[index] end),',')
        local card = U.askForUseRealCard(room,player,player:getHandlyIds(true),".|.|.|.|.|"..type,self.name,"#liehe_askUse",nil,true)
        if card then
          self.cost_data.card = card
          self.cost_data.operation = 1
          return true
        end
      elseif choice:startsWith("liehe_get") then
        local all_choices1 = {"liehe_get::"..to.id,"liehe_move_other::"..to.id}
        local choices1 = {}
        if not #to:getCardIds("e") then
          choices1 = {all_choices1[2]}
        elseif not #moveTargets then
          choices1 = {all_choices1[1]}
        else
          choices1 = all_choices1
        end
        choice = room:askForChoice(to,choices1,self.name,"liehe_choose",false,all_choices1)
        if choice:startsWith("liehe_get") then
            local card = room:askForCard(to,1,1,true,self.name,false,".|.|.|.|.|equip","#liehe_getEquip")
          if card then
            self.cost_data.card = card
            self.cost_data.executor = to
            self.cost_data.operation = 2
            return true
          end
        else
          local moveTo = room:askForChoosePlayers(to,table.map(moveTargets,Util.IdMapper),1,1,"liehe_choose2Move",self.name,false)
          if moveTo and #moveTo > 0  then
            self.cost_data.target = room:getPlayerById(moveTo[1])
            self.cost_data.executor = to
            self.cost_data.operation = 3
            return true
          end
        end
      end
      return true
    elseif difference == 2 and player:canMoveCardsInBoardTo(to,"e") then
      if room:askForSkillInvoke(player,self.name,nil,"liehe_move_to:"..to.id..":"..player.id) then
        self.cost_data = {executor = player,operation = 3,target = to}
        return true
      end
    elseif difference == -2 and to:canMoveCardsInBoardTo(player,"e") then
      if room:askForSkillInvoke(player,self.name,nil,"liehe_move_to:"..player.id ..":"..to.id) then
        self.cost_data = {executor = to,operation = 3,target = player}
        return true
      end
    elseif target == player then
      local moveTargets = table.filter(room:getOtherPlayers(player),function (element, index, array)
        return to:canMoveCardsInBoardTo(element,"e")
      end)
      local all_choices = {"liehe_use_unlimited::"..player.id,"liehe_get::"..player.id,"liehe_move_other::"..player.id,"Cancel"}
      local can_choose = {true,#player:getCardIds("e")>0,#moveTargets>0,true}
      local choices = table.filter(all_choices,function (element, index, array)
        return can_choose[index]
      end)
      local choice = room:askForChoice(player,choices,self.name,"#liehe_use",false,all_choices)
      if choice == "Cancel" then
        return false
      elseif choice:startsWith("liehe_use") then
        local card =U.askForUseRealCard(room,player,player:getHandlyIds(true),".|.|.|.|.|equip",self.name,"#liehe_askUse",nil,true)
        if card then
          self.cost_data.card = card
          self.cost_data.operation = 1
          return true
        end
      elseif choice:startsWith("liehe_get") then
        local card = room:askForCard(player,1,1,true,self.name,true,".|.|.|.|.|equip","#liehe_getEquip")
        if card then
          self.cost_data.card = card
          self.cost_data.executor = player
          self.cost_data.operation = 2
          return true
        end
      else
        local moveTo = room:askForChoosePlayers(player,table.map(moveTargets,Util.IdMapper),1,1,"liehe_choose2Move",self.name,false)
        if moveTo and #moveTo > 0 then
          self.cost_data.target = room:getPlayerById(moveTo[1])
          self.cost_data.executor = player
          self.cost_data.operation = 3
          return true
        end
      end
    elseif difference == 0 and #player:getCardIds("e")>0 then
      local choices = {"liehe_replace::"..player.id,"liehe_replace::"..to.id,"Cancel"}
      local choice = room:askForChoice(player,choices,self.name)
      if choice == "Cancel" then return end
      if choice == choices[1] then
        to = player
      end
      local type = table.concat(table.map(
          table.filter({Card.SubtypeWeapon, Card.SubtypeArmor, Card.SubtypeDefensiveRide,Card.SubtypeOffensiveRide, Card.SubtypeTreasure}, 
            function (type_name) return to:getEquipment(type_name) ~= nil end),
          function (element, index, array)return types[index]end),',')
      local card = U.askForUseRealCard(room,to,to:getHandlyIds(true),".|.|.|.|.|"..type,self.name,"#liehe_askUse",nil,true)
      if card then
        self.cost_data.card = card
        self.cost_data.operation = 1
        return true
      end
    end
    
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if self.cost_data.operation == 1 then
      room:useCard(self.cost_data.card)
    elseif self.cost_data.operation == 2 then
      room:obtainCard(self.cost_data.executor,self.cost_data.card,false,fk.ReasonPrey,player.id,self.name)
    elseif self.cost_data.operation == 3 then
      room:askForMoveCardInBoard(self.cost_data.executor,self.cost_data.executor,self.cost_data.target,self.name,"e",self.cost_data.executor)
    end
  end
}
Fk:loadTranslationTable{
  ["xiaobai__liehe"] = "列合",
  [":xiaobai__liehe"] = "你失去过牌的回合结束时，可令你或当前回合角色执行恰好能使装备区牌数等于对方的一项：1.可以使用一张装备牌；2.收回或移动自己场上一张装备牌。",
  ["liehe_use"] = "令 %dest 使用一张其空置装备栏对应副类别的装备牌",
  ["liehe_use_unlimited"] = "令 %dest 使用一张装备牌",
  ["liehe_replace"] = "令 %dest 使用一张装备牌以替换装备区里已有的装备牌",
  ["liehe_get"] = "令 %dest 获得自己装备区一张装备牌",
  ["liehe_move_other"] = "令 %dest 将一张装备牌移动至其他角色的装备区",
  ["#liehe_use"] = "你可以发动列合：选择一项",
  ["#liehe_askUse"] = "你可以使用一张对应副类别的装备牌",
  ["liehe_choose2Move"] = "你选择一其他名角色然后需将一张装备牌移至其角色的装备区",
  ["liehe_move_to"] = "列合：你可以令 %dest 将装备区的的一张牌移动至 %src 的对应区域",  
  ["#liehe_getEquip"] = "列合：你须获得自己的一张装备牌",
  ["liehe_get_or_move_other"] = "令 %dest 获得自己一张装备装备区的牌或将装备区牌移给其他角色", 
  ["liehe_choose"] = "列合：选择一项"
}

sunshao:addSkill(leicheng)
sunshao:addSkill(liehe)


local xuci = General(extension,"xiaobai-twelve__xuci", "shu", 3)

Fk:loadTranslationTable{
  ["xiaobai-twelve__xuci"] = "许慈",
  ["#xiaobai-twelve__xuci"] = "鹬身诽蚌",
  ["illustrator:xiaobai-twelve__xuci"] = "SD&查无",
  ["designer:xiaobai-twelve__xuci"] = "宫商催角羽",

  ["xiaobai__huisu"] = " 毁诉",
  [":xiaobai__huisu"] = "出牌阶段限一次，你可选择一名有牌的其他角色依次对其执行：议事，拼点，视为使用【决斗】，"..
    "然后若你<a href=':xiaobai__huisu-detail'>赢</a>的次数大于对方，你可以重铸至多三张牌。"..
    "每执行一项，若有赢的角色，其获得因上一项双方展示或失去过的手牌。",
  ["@@huisu"] = "毁诉",
  ["@$huisu"] = "毁诉",
  ["huisu__recast"] = "毁诉：你可以重铸至多三张牌",
  [":xiaobai__huisu-detail"] = "拼点牌大于对方，在【决斗】唯一对对方造成伤害的角色为赢的角色。",
  ["xiaobai__boshe"] = "博涉",
  [":xiaobai__boshe"] = "一名角色的回合结束时，若当前回合角色本回合恰好以四种不同的方式失去过牌，你可以摸一张牌并与其各获得一张【影】。"
}

local huisu = fk.CreateActiveSkill{
  name = "xiaobai__huisu",
  target_num = 1, 
  target_filter = function (self, to_select, selected, selected_cards, card, extra_data)
    return to_select ~= Self.id and (not selected or #selected == 0) and Fk:currentRoom():getPlayerById(to_select):getHandcardNum() > 0
  end,
  can_use = function (self, player, card, extra_data)
    return player:usedSkillTimes(self.name,Player.HistoryPhase) < 1
  end,
  on_use = function (self, room, effect)
    local target = room:getPlayerById(effect.tos[1])
    local player = room:getPlayerById(effect.from)
    local end_id = room.logic:getCurrentEvent().id
    local win = 0
    local other_win = 0
    local to_get = {}
    --议事
    local discussion = nil
    if player:getHandcardNum() > 0 then
      discussion = U.Discussion(player,{player,target},self.name)
      if discussion then
        table.insertTable(to_get,discussion.results[player.id].toCards)
        table.insertTable(to_get,discussion.results[target.id].toCards) 
      end
    end
    if player.dead then
      return
    end
    --拼点
    local pindian = nil
    if player:getHandcardNum() > 0 then
      local pindian = player:pindian({target},self.name)
      if player.dead then
        return
      end
      if pindian.results[target.id].winner and #to_get > 0 then
        if pindian.results[target.id].winner == player then
          win = win+1
          to_get = table.filter(to_get,function (element, index, array)
            return table.indexOf(player:getCardIds("h"),element) == -1
          end)
          room:obtainCard(player, to_get, true)
          to_get = {}
        elseif pindian.results[target.id].winner == target then
          other_win = other_win + 1
          to_get = table.filter(to_get,function (element, index, array)
            return table.indexOf(target:getCardIds("h"),element) == -1
          end)
          room:obtainCard(target, to_get, true)
          to_get = {}
        else
          to_get = {}
        end
      end
      --记录拼点牌
      local card = pindian.fromCard
      if room.logic:getEventsByRule(GameEvent.MoveCards,1,function (e)
        for _, move in ipairs(e.data) do
          if move.from == player.id and move.moveReason == 1 then
            for _, info in ipairs(move.moveInfo) do
              if info.cardId == card.id then
                return true
              end
            end
          end
        end
      end,end_id) then
        table.insertIfNeed(to_get,card)
      end
      card = pindian.results[target.id].toCard
      if room.logic:getEventsByRule(GameEvent.MoveCards,1,function (e)
        for _, move in ipairs(e.data) do
          if move.from == player.id and move.moveReason == 1 then
            for _, info in ipairs(move.moveInfo) do
              if info.cardId == card.id then
                return true
              end
            end
          end
        end
      end,end_id) then
        table.insertIfNeed(to_get,card)
      end
    end
    --使用【决斗】
    local duel = Fk:cloneCard("duel") 
    duel.skillName = self.name
    if U.canUseCard(room,player,duel,false) then
      if player.dead then
        return
      end
      local use = {
        from = player.id,
        tos = {{target.id}},
        card = duel,
      }
      room:useCard(use)
      if use.damageDealt then
        if use.damageDealt[player.id] and not use.damageDealt[target.id] then
          other_win = other_win+1
          to_get = table.filter(to_get,function (element, index, array)
            return table.indexOf(target:getCardIds("h"),element) == -1
          end)
          room:obtainCard(target,to_get,true,fk.ReasonPrey,player.id,self.name)
        elseif not use.damageDealt[player.id] and use.damageDealt[target.id] then
          win = win+1
          to_get = table.filter(to_get,function (element, index, array)
            return table.indexOf(player:getCardIds("h"),element) == -1
          end)
          room:obtainCard(player,to_get,true,fk.ReasonPrey,player.id,self.name)
        end
      end
    end
    if player.dead then return end
    if win > other_win then
      local recast = room:askForCard(player,1,3,true,self.name,true,".","huisu__recast");
      if recast and #recast > 0 then 
        room:recastCard(recast,player,self.name)
      end
    end
  end
}

local getShade = function (room, n)
  n = n or 1
  local ids = {}
  local name
  if Fk.all_card_types["shade"] then
    name = "shade"
  elseif Fk.all_card_types["rfenghou__shade"] then
    name = "rfenghou__shade"
  end
  assert(name, "服务器未加入【影】！请联系管理员安装“江山如故”或“封侯”包")
  for _, id in ipairs(room.void) do
    if n <= 0 then break end
    if Fk:getCardById(id).name == name then
      room:setCardMark(Fk:getCardById(id), MarkEnum.DestructIntoDiscard, 1)
      table.insert(ids, id)
      n = n - 1
    end
  end
  while n > 0 do
    local card = room:printCard(name, Card.Spade, 1)
    room:setCardMark(card, MarkEnum.DestructIntoDiscard, 1)
    table.insert(ids, card.id)
    n = n - 1
  end
  return ids
end

local boshe = fk.CreateTriggerSkill{
  name = "xiaobai__boshe",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    local way_lost = {}
    player.room.logic:getEventsOfScope(GameEvent.MoveCards,1,function (e)
      for _, move in ipairs(e.data) do
        if move.from == target.id then
          table.insertIfNeed(way_lost,move.moveReason)
        end
      end
    end,Player.HistoryTurn)
    if #way_lost >= 4 then
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    player.room:drawCards(player,1,self.name)
    if player.dead then return end
    player.room:moveCardTo(getShade(player.room, 1), Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
    if player.dead then return end
    player.room:moveCardTo(getShade(player.room, 1), Card.PlayerHand, target, fk.ReasonJustMove, self.name, nil, true, player.id)
  end
  
}

xuci:addSkill(huisu)
xuci:addSkill(boshe)

local wangsi = General(extension,"xiaobai-twelve__wangsi", "shu",4)

Fk:loadTranslationTable{
  ["xiaobai-twelve__wangsi"] = "王嗣",
  ["#xiaobai-twelve__wangsi"] = "北固山盟",
  ["illustrator:xiaobai-twelve__wangsi"] = "梦回唐朝",
  ["designer:xiaobai-twelve__wangsi"] = "cyc",

  ["xiaobai__qinrong"] = " 亲戎",
  [":xiaobai__qinrong"] = "摸牌阶段，你可以改为视为使用一张【远交近攻】，然后你与此牌的目标议事，若议事有结果，其变更势力至与你相同。",
  ["#xiaobai__qinrong_prompt"] = "亲戎：你可以放弃摸牌改为视为使用一张【远交近攻】，然后你与此牌的目标议事，若议事有结果，其变更势力至与你相同。",
  ["xiaobai__fuqing"] = "扶倾",
  [":xiaobai__fuqing"] = "每轮限一次，一张【杀】指定目标后，若途经你或目标为你，你可以令之无效，然后视为使用一张【以逸待劳】，"..
    "然后此【杀】的使用者可使用至多X张因此弃置的牌（X为【以逸待劳】的目标数）。",
  ["#xiaobai__fuqing_prompt"] = "扶倾：你可以令此【杀】无效并视为使用【以逸待劳】然后 %dest 可使用至多X张因此弃置的牌（X为【以逸待劳】的目标数）",
  ["#xiaobai__fuqing_extraUsePrompt"] = "扶倾：你可以视为其中至多 %arg 张牌" 
}

local qinrong = fk.CreateTriggerSkill{
  name = "xiaobai__qinrong",
  events = {fk.DrawNCards},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player
  end,
  on_cost = function (self, event, target, player, data)
    local use = U.askForUseVirtualCard(player.room, player, "befriend_attacking", nil, self.name, "#xiaobai__qinrong_prompt", true, true, true, true, nil, true)
    if use then
      self.cost_data = use
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    data.n = 0
    room:useCard(self.cost_data)
    if player.dead then return end
    local target = room:getPlayerById(TargetGroup:getRealTargets(self.cost_data.tos)[1])
    local discussion = U.Discussion(player, {player, target}, self.name)
    if target.dead then return true end
    if discussion.color ~= "noresult" then
      room:changeKingdom(target, player.kingdom)
    end
    return true
  end
}

wangsi:addSkill(qinrong)
---从from到target是否经过pass
---@param from ServerPlayer
---@param target ServerPlayer
---@param pass ServerPlayer
---@return boolean
local passPlayer = function (from, target, pass)
  if target == from then return false end
  local p = from:getNextAlive()
  local num1,num2 = 1,1
  local judge1,judge2 = false,false
  while p ~= from do
    if p == pass then 
      judge1 = true 
    end
    if p == target then 
      break 
    end
    p = p:getNextAlive()
    num1 = num1 + 1
  end
  p = from:getLastAlive()
  while p ~= from do
    if p == pass then 
      judge2 = true
    end
    if p == target then 
      break 
    end
    p = p:getLastAlive()
    num2 = num2 + 1
  end
  if num1 < num2 then
    return judge1
  elseif num1 > num2 then
    return judge2
  else
    return judge1 or judge2
  end
end

local fuqing = fk.CreateTriggerSkill{
  name = "xiaobai__fuqing",
  events = {fk.TargetSpecified},
  anim_type = "support",
  ---@param data AimStruct
  can_trigger = function (self, event, target, player, data)
    if not (player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryRound) < 1 and data.firstTarget and data.card.trueName == "slash") then return end
    local targets = AimGroup:getAllTargets(data.tos)
    if table.contains(targets, player.id) then return true end
    for _, tid in ipairs(targets) do
      if passPlayer(target, player.room:getPlayerById(tid), player) then
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local use = U.askForUseVirtualCard(room, player, "await_exhausted", nil, self.name, "#xiaobai__fuqing_prompt::"..target.id, true, true, true, true, nil, true)
    if use then
      self.cost_data = use
      return true
    end
  end,
  ---@param data AimStruct
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:addPlayerMark(player, "xiaobai__fuqing_using")
    local cardTargets = #Fk:cloneCard("await_exhausted"):getAvailableTargets(player)
    room:useCard(
      self.cost_data
    )
    local cards = player:getTableMark("xiaobai__fuqing_discards")
    for i = 1, cardTargets, 1 do
      local use = U.askForUseRealCard(room, target, cards, ".", self.name, "#xiaobai__fuqing_extraUsePrompt:::"..(cardTargets - i + 1), {bypass_times = true,expand_pile = cards}, true)
      if not use then break end
      table.removeOne(cards, use.card.id)
      room:useCard(use)
      if target.dead then return end
      if #cards == 0 then break end
    end
    room:setPlayerMark(player, "xiaobai__fuqing_discards", 0)
    room:setPlayerMark(player, "xiaobai__fuqing_using", 0)
    table.insertTableIfNeed(data.nullifiedTargets,table.map(room:getAlivePlayers(),Util.IdMapper))
    return true
  end,
  refresh_events = {fk.AfterCardsMove},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self.name) and player:getMark("xiaobai__fuqing_using") ~= 0
  end,
  ---@param data CardsMoveStruct[]
  on_refresh = function (self, event, target, player, data)
    for _, move in ipairs(data) do
      if move.moveReason == fk.ReasonDiscard and move.skillName and move.skillName and move.skillName == "await_exhausted_skill" then
        for _, info in ipairs(move.moveInfo) do
          player.room:addTableMark(player, "xiaobai__fuqing_discards", info.cardId)
        end
      end
    end
  end
}

wangsi:addSkill(fuqing)

local lisheng = General(extension,"xiaobai-twelve__lisheng", "wei",3)

local tanxu = fk.CreateActiveSkill  {
  name = "xiaobai__tanxu",
  anim_type = "offensive",
  prompt = "#tanxu__prompt",
  can_use = function (self, player, card, extra_data)
    return player:usedSkillTimes(self.name)<1 and #Fk:currentRoom().alive_players > 1
  end,
  card_filter = Util.FalseFunc,
  on_use = function (self, room, effect)
    local player = room:getPlayerById(effect.from)
    player.room:moveCardTo(getShade(room, 1), Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
    if player.dead then return end
    local targets = table.map(room:getOtherPlayers(player),Util.IdMapper)
    local target = room:askForChoosePlayers(player,targets,1,1,"#tanxu__choose_user",self.name,false)
    room:useVirtualCard("sincere_treat",nil,room:getPlayerById(target[1]),{player},self.name,true)
    if player.dead then return end
    room:showCards(player:getCardIds("h"),player)
    if player.dead then return end
    if table.find(player:getCardIds("h"),function (element, index, array)
      return Fk:getCardById(element).trueName == "shade"
    end) then
      if room:askForSkillInvoke(player,self.name,nil,"#tanxu__damage::"..target[1]) then
        room:damage{
          from = player,
          to = room:getPlayerById(target[1]),
          damage = 1,
          skillName = self.name
        }
      end
    end
  end
}

local danglian = fk.CreateTriggerSkill{
  name = "xiaobai__danglian",
  anim_type = "offensive",
  events = {fk.AfterCardsMove,fk.DamageInflicted},
  can_trigger = function (self, event, target, player, data)
    if event == fk.AfterCardsMove then
      if not player:hasSkill(self) or player:getMark("danglian1-turn")>0 or player.chained then return end
      if player:hasSkill(self)then
        for _, move in ipairs(data) do
          if move.from == player.id and move.moveReason ~= fk.ReasonUse and move.moveReason ~= fk.ReasonResonpse then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                return true
              end
            end
          end
        end
      end
    else
      if not player:hasSkill(self) or player:getMark("danglian2-turn")>0 or not player.chained or target ~= player then return end
      if data.damageType == fk.NormalDamage then
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.AfterCardsMove then
      return player.room:askForSkillInvoke(player,self.name,nil,"#danglian__draw")
    else
      return player.room:askForSkillInvoke(player,self.name,nil,"#danglian__prevent")
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardsMove then
      room:addPlayerMark(player,"danglian1-turn",1)
      player:setChainState(true)
      if player.dead then return end
      player:drawCards(2,self.name)
      
    else
      room:addPlayerMark(player,"danglian2-turn",1)
      player:setChainState(false)
      if player.dead then return end
      return true
    end
  end
}

lisheng:addSkill(tanxu)
lisheng:addSkill(danglian)

Fk:loadTranslationTable{
  ["xiaobai-twelve__lisheng"] = "李胜",
  ["#xiaobai-twelve__lisheng"] = "虚才雅智",
  ["illustrator:xiaobai-twelve__lisheng"] = "CWGYH",
  ["designer:xiaobai-twelve__lisheng"] = "胖即是胖",
  ["cv:xiaobai-twelve__lisheng"] = "cyc",

  ["~xiaobai-twelve__lisheng"] = "怀宠禄、虑子孙，岂可作社稷臣？",

  ["xiaobai__tanxu"] = "探虚",
  [":xiaobai__tanxu"] = "出牌阶段限一次，你可以获得一张【影】然后令一名其他角色视为对你使用【推心置腹】。"..
    "此牌结算后你展示所有手牌，若其中有【影】，你可以对其造成1点伤害。",
    
  ["#tanxu__prompt"] = "探虚：你可以获得一张【影】然后令一名其他角色视为对你使用【推心置腹】。"..
    "此牌结算后你展示所有手牌，若其中有【影】，你可以对其造成1点伤害",
  ["#tanxu__choose_user"] = "探虚：请选择视为对你使用【推心置腹】的角色",
  ["#tanxu__damage"] = "探虚：是否对 %dest 造成1点伤害",

  ["$xiaobai__tanxu1"] = "外间谓公旧风发动，何意乃尔！",
  ["$xiaobai__tanxu2"] = "荆南风物、边陲治要，愿太傅教我。",
  
  ["xiaobai__danglian"] = "党连",
  [":xiaobai__danglian"] = "每回合各限一次，你不因使用或打出失去牌后，你可以横置并摸两张牌；你受到非属性伤害时，你可以重置并防止此伤害。",
  ["#danglian__draw"] = "党连：你可以横置并摸两张牌",
  ["#danglian__prevent"] = "党连：你可以重置并防止此伤害",

  ["$xiaobai__danglian1"] = "司马公尸居余气，形神已离，不足虑矣。",
  ["$xiaobai__danglian2"] = "兵可立威，此役伐蜀，大将军当建奇功。"

}

local jiangshu = General(extension,"xiaobai-twelve__jiangshu", "shu",4)
jiangshu.hidden = true

Fk:loadTranslationTable{
  ["xiaobai-twelve__jiangshu"] = "蒋舒",
  ["#xiaobai-twelve__jiangshu"] = "敬请期待",
  ["illustrator:xiaobai-twelve__jiangshu"] = "白教堂",
  ["designer:xiaobai-twelve__jiangshu"] = "敬请期待"
}


local baochu = General(extension,"xiaobai-twelve__baochu", "qun",4)

local ziren = fk.CreateViewAsSkill{
  name = "xiaobai__ziren",
  pattern = "slash",
  anim_type = "offensive",
  card_num = 3,
  prompt = "#xiaobai__ziren",
  card_filter = function (self, to_select, selected, player)
    return not selected or #selected < 3
  end,
  view_as = function (self, cards)
    if #cards ~= 3 then
      return
    end
    local card = Fk:cloneCard("slash")
    card.skillName = self.name
    card:addSubcards(cards)
    local c = table.map(cards,function (element, index, array)
      return Fk:getCardById(element)
    end)
    if c[1].type == c[2].type and c[2].type == c[3].type then
      card.extra_data = card.extra_data or {}
      card.extra_data.xiaobai__ziren = true
    end
    return card
  end,
  before_use = function (self, player, use)
    if not use.card.extra_data or not use.card.extra_data.xiaobai__ziren then
      return
    end
    local room = player.room
    use.disresponsiveList = table.map(room.alive_players, Util.IdMapper)
    local targets = TargetGroup:getRealTargets(use.tos)
    local tos = room:getUseExtraTargets(use,true)
    if #tos > 0 then
      tos = room:askForChoosePlayers(player, tos, 1, 999, "#ziren_chooseTarget", self.name, false, true)
      table.insertTable(targets, tos)
      room:sortPlayersByAction(targets)
      use.tos = table.map(targets, function(p) return {p} end)
      room:sendLog{
        type = "#AddTargetsBySkill",
        from = player.id,
        to = tos,
        arg = self.name,
        arg2 = use.card:toLogString()
      }
    end
  end,
  enabled_at_response = function (self,player,response)
    return not response
  end,
  enabled_at_play = Util.TrueFunc;
}

baochu:addSkill(ziren)

local renxie = fk.CreateTriggerSkill{
  name = "xiaobai__renxie",
  events = {fk.TargetSpecified,fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if event == fk.TargetSpecified then
      return (target == player and player:hasSkill(self) and (data.firstTarget and #AimGroup:getAllTargets(data.tos) > 0 and data.card.is_damage_card) 
      or player:getMark("#renxie_damage") ~= 0)
    else
      return data.from and data.from == player and data.card and data.card.extra_data and data.card.extra_data.xiaobai__renxie and
        target.hp < target.maxHp and not target:isNude()
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TargetSpecified then
      if data.firstTarget then
        return player.room:askForSkillInvoke(player,self.name,nil,"#renxie_get")
      else
        return true
      end
    else
      return player.room:askForSkillInvoke(target,self.name,nil,"#renxie_give::"..player.id)
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.TargetSpecified then
      if data.firstTarget then
        local card = data.card
      card.skillName = self.name
      table.forEach(AimGroup:getAllTargets(data.tos),function (element, index, array)
        element = player.room:getPlayerById(element)
        if element:isNude() then
          return
        end
        local cards = player.room:askForCard(element,1,#element:getCardIds("he"),true,self.name,false,".")
        player.room:obtainCard(player,cards,false,fk.ReasonGive,element.id,self.name)
      end)

      local num  = {false,false,false}
      local hurt = 2
      table.forEach(player:getCardIds("h"),function (element, index, array)
        local card = Fk:getCardById(element)  
        if num[card.type] == false then
          hurt = hurt - 1
          num[card.type] = true
        end
      end)
      data.additionalDamage = (data.additionalDamage or 0) + hurt
      player.room:setPlayerMark(player,"#renxie_damage",hurt)
      local use = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard,false)
      use:addCleaner(function ()
        player.room:setPlayerMark(player,"#renxie_damage",0)
      end)
      data.card.extra_data = data.card.extra_data or {}
      data.card.extra_data.xiaobai__renxie = true
      else
        data.additionalDamage = (data.additionalDamage or 0) + player:getMark("#renxie_damage")
      end
    else
      local card = player.room:askForCardChosen(player,target,"he",self.name)
      if not card then return end
      self.cost_data = self.cost_data or {}
      self.cost_data.card = card
      player.room:obtainCard(player,self.cost_data.card,false,fk.ReasonGive,player.id,self.name)
      if target.dead then return end
      player.room:recover{
        who = target,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      }
    end
  end,
}

baochu:addSkill(renxie)
AddWinAudio(baochu)

Fk:loadTranslationTable{
  ["xiaobai-twelve__baochu"] = "鲍出",
  ["#xiaobai-twelve__baochu"] = "奋袂攘臂",
  ["illustrator:xiaobai-twelve__baochu"] = "匠人绘",
  ["designer:xiaobai-twelve__baochu"] = "小叶子",
  ["cv:xiaobai-twelve__baochu"] = "超天酱",

  ["xiaobai__ziren"] = "眦刃",
  [":xiaobai__ziren"] = "你可以将三张牌当不可响应的【杀】使用，若类别均相同，你使用以此法转化的【杀】可额外指定任意名目标（无距离限制）。",
  ["#xiaobai__ziren"] = "眦刃：你可以将三张牌当不可相应【杀】使用，若类别相同则可额外指定任意名目标（无距离限制）。",
  ["#ziren_chooseTarget"] = "眦刃：你可以额外指定任意名目标（无距离限制）",
  ["xiaobai__renxie"] = "衽挟",
  [":xiaobai__renxie"] = "你使用伤害牌指定目标后，可令目标角色依次交给你至少一张牌，则将此牌的伤害值改为你手牌中缺少的类别数。"..
    "目标角色因此受到伤害后，其可以令你获得其一张牌，然后回复1点体力。",
  ["#renxie_get"] = "衽挟：你可令目标角色依次交给你至少一张牌，然后将此牌的伤害值改为你手牌中缺少的类别数。",
  ["#renxie_give"] = "衽挟：你可以令 %dest 获得你一张手牌，然后你回复1点体力。",

  ["$xiaobai__ziren1"] = "婢儿学人执兵，却敢窥视某家？",
  ["$xiaobai__ziren2"] = "睚眦尚见血，今番必斫些头颅。",
  ["$xiaobai__renxie1"] = "蟊贼听真：一刻不见老母，某便再剖一人。",
  ["$xiaobai__renxie2"] = "某家新丰鲍文才，好生思量，莫要自误。",
  ["~xiaobai-twelve__baochu"] = "竖子！狗囊！截你爷头！",
  ["$xiaobai-twelve__baochu_win_audio"] = "母亲！儿无恙，衣裳所沾尽是贼人血。"
}

local zhaoqi = General(extension,"xiaobai-twelve__zhaoqi", "qun",3)

local quanyi_viewAs = fk.CreateViewAsSkill{
  name = "#quanyi_viewAs",
  pattern = ".",
  interaction = function (self, player)
    local used_cards = player:getTableMark("@$xiaobai__quanyi")
    if used_cards == 0 then used_cards = {} end
    local all_names = U.getAllCardNames("bt")
    return UI.CardNameBox {
      choices = player:getViewAsCardNames(Self, "xiaobai__quanyi", all_names, nil, used_cards),
      all_choices = all_names,
      default_choice = "AskForCardsChosen"
    }
  end,
  card_filter = Util.FalseFunc;
  view_as = function (self, cards, player)
    if self.interaction.data == "AskForCardsChosen" or nil then return nil end
    return Fk:cloneCard(self.interaction.data)
  end
}
Fk:addSkill(quanyi_viewAs)

local quanyi = fk.CreateTriggerSkill{
  name = "xiaobai__quanyi",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and player:getLastAlive() == target and player:usedSkillTimes(self.name, Player.HistoryRound) < 1
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local next = player:getNextAlive()
    return room:askForSkillInvoke(player, self.name, nil, "@xiaobai__quanyi_prompt::"..next.id)
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local next = player:getNextAlive()
    local did =  next:getMark("@@xiaobai__quanyi") > 0 
    room:swapSeat(player, next)
    room:addPlayerMark(next, "@@xiaobai__quanyi")
    if player.dead then return end
    local _,use = room:askForUseViewAsSkill(player, quanyi_viewAs.name, "@xiaobai__quanyi_use_prompt")
    if not use then return end
    
    local card = Fk:cloneCard(use.interaction)
    card.skillName = self.name
    room:useCard{
      card = card,
      from = player.id,
      tos = table.map(use.targets, function(e) return {e} end),
      skillName = self.name
    }
    if player.dead then return end
    room:addTableMark(player, "@$xiaobai__quanyi", use.interaction)
    if did then
      local cardNames = player:getTableMark("@$xiaobai__quanyi")
      if cardNames == 0 then return end
      for _, cardName in ipairs(cardNames) do
        U.askForUseVirtualCard(room, player, cardName, nil, self.name)
      end
      room:handleAddLoseSkills(player, "-"..self.name)
    end
  end,
  refresh_events = {fk.EventLoseSkill},
  can_refresh = function (self, event, target, player, data)
    return data == self and target == player
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@$xiaobai__quanyi", 0)
  end
}

local chenguang = fk.CreateTriggerSkill{
  name = "xiaobai__chenguang",
  events = {fk.PreHpRecover, fk.DamageInflicted, fk.AfterDrawPileShuffle},
  anim_type = "support",
  dynamic_desc = function (self, player, lang)
    if player:getMark("@@xiaobai__chenguang") > 0 then
      return "xiaobai__chenguang_fix"
    else
      return "xiaobai__chenguang"
    end
  end,
  can_trigger = function (self, event, target, player, data)
    local room = player.room
    if event == fk.DamageInflicted then
      if target == player and player:hasSkill(self) then
        return #room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function (e)
          for _, move in ipairs(e.data) do
            if move.to == player.id and move.from ~= player.id 
            and (move.toArea == Card.PlayerHand or move.toArea == Card.PlayerEquip) then
              return true
            end
          end
        end, Player.HistoryRound) == 0
      end
    elseif event == fk.PreHpRecover then
      if target == player and player:hasSkill(self) then
        return #room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function (e)
          for _, move in ipairs(e.data) do
            if move.from == player.id and move.to ~= player.id then
              for _, info in ipairs(move.moveInfo) do
                if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                  return true
                end
              end
            end
          end
        end, Player.HistoryRound) == 0    
      end
    else
      return player:getMark("@@xiaobai__chenguang") == 0
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.PreHpRecover then
      if player:getMark("@@xiaobai__chenguang") > 0 then
        return room:askForSkillInvoke(player, self.name, nil, "#xiaobai__chenguang_recover2_prompt")
      else
        local cards = room:askForDiscard(player, 1, 1, true, self.name, true, ".", "#xiaobai__chenguang_recover1_prompt:::"..data.num, true)
        if #cards > 0 then
          self.cost_data = cards[1]
          return true
        end
      end
    elseif event == fk.DamageInflicted then
      if player:getMark("@@xiaobai__chenguang") > 0 then
        local cards = room:askForDiscard(player, 1, 1, true, self.name, true, ".", "#xiaobai__chenguang_damage2_prompt:::"..data.num, true)
        if #cards > 0 then
          self.cost_data = cards[1]
          return true
        end
      else
        return room:askForSkillInvoke(player, self.name, nil, "#xiaobai__chenguang_damage1_prompt")
      end
    else
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.PreHpRecover then
      if player:getMark("@@xiaobai__chenguang") > 0 then
        player:drawCards(1, self.name)
      else
        room:throwCard(self.cost_data, self.name, player)
      end
      data.num = data.num * 2
    elseif event == fk.DamageInflicted then
      if player:getMark("@@xiaobai__chenguang") > 0 then
        room:throwCard(self.cost_data, self.name, player)
      else
        player:drawCards(1, self.name)
      end
      return true
    else
      room:addPlayerMark(player, "@@xiaobai__chenguang")
    end
  end
}

zhaoqi:addSkill(quanyi)
zhaoqi:addSkill(chenguang)

Fk:loadTranslationTable{
  ["xiaobai-twelve__zhaoqi"] = "赵岐",
  ["#xiaobai-twelve__zhaoqi"] = "苦无时命",
  ["designer:xiaobai-twelve__zhaoqi"] = "扬林",
  ["illustrator:xiaobai-twelve__zhaoqi"] = "强强&小猫",

  ["xiaobai__quanyi"] = "权宜",
  [":xiaobai__quanyi"] = "每轮限一次，你的上家回合结束时，你可以与下家交换位置，"..
    "然后可视为使用一张未以此法使用过的基本牌或普通锦囊牌，若你曾与该角色交换过位置，则你再视为使用任意张以此法使用过的牌，然后失去此技能。",
  ["#quanyi_viewAs"] = "权宜",
  ["@xiaobai__quanyi_prompt"] = "权宜：你可以与 %dest 交换位次",
  ["@xiaobai__quanyi_use_prompt"] = "权宜：你可以视为使用一张基本牌或普通锦囊牌",
  ["@$xiaobai__quanyi"] = "权宜",
  ["@@xiaobai__quanyi"] = "权宜 已换位",

  ["xiaobai__chenguang"] = "沉光",
  [":xiaobai__chenguang"] = "你受到伤害时，若你本轮未获得过牌，你可以摸一张牌，防止之；"..
    "你回复体力时，若你本轮未失去过牌，你可以弃置一张牌，翻倍之。牌堆洗牌后，<a href=':xiaobai__chenguang_fix'>修改</a>此技能。",
  ["@@xiaobai__chenguang"] = "沉光 已修改",
  ["#xiaobai__chenguang_recover1_prompt"] = "沉光：你可以弃置一张牌，额外回复 %arg 点体力",
  ["#xiaobai__chenguang_recover2_prompt"] = "沉光：你可以摸一张牌，额外回复 %arg 点体力",
  ["#xiaobai__chenguang_damage1_prompt"] = "沉光：你可以摸一张牌，防止此伤害",
  ["#xiaobai__chenguang_damage2_prompt"] = "沉光：你可以弃一张牌，防止此伤害",
  ["xiaobai__chenguang_fix"] = "沉光",
  [":xiaobai__chenguang_fix"] = "你受到伤害时，若你本轮获得过牌，你可以弃置一张牌，防止之；你回复体力时，若你本轮失去过牌，你可以摸一张牌，翻倍之。"
}

return extension 